package com.netcracker.training.automonic.parser.csv;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

import org.apache.log4j.Logger;

import au.com.bytecode.opencsv.CSVReader;

import com.netcracker.training.automonic.dao.entities.Attribute;
import com.netcracker.training.automonic.dao.entities.AttributeType;
import com.netcracker.training.automonic.dao.entities.Object;
import com.netcracker.training.automonic.dao.entities.Site;
import com.netcracker.training.automonic.dao.entities.Statistics;
import com.netcracker.training.automonic.dao.entities.StatsType;
import com.netcracker.training.automonic.dao.factories.DAOFactory;
import com.netcracker.training.automonic.dao.roles.ReadWriteDAO;
import com.netcracker.training.automonic.parser.Parser;

/**
 * Concrete parser for *.csv files
 * 
 * @author Vadim Gidulyan
 *
 */
public class CSVParser implements Parser // TODO Javadoc
{

	public static final Logger LOGGER = Logger.getLogger(CSVParser.class);
	
	/*
	 * Ticker, Company, Sector, Industry, Country, 
	 * Market Cap, P/E, Price, Change, Volume
	 * 
	 */
	
	private final String PATH = "C:\\finviz\\finviz_20140123.csv";
	
	private Site site;
	private CSVReader csvReader;
	private ReadWriteDAO dao;
	private String[] titles;
	private String[] entry;
	
	/*
		String number    = entry[0],
		       ticker    = entry[1],
		       company   = entry[2],
		       sector    = entry[3],
		       industry  = entry[4],
		       country   = entry[5],
		       marketCap = entry[6],
		       pe        = entry[7],
		       price     = entry[8],
		       change    = entry[9],
		       volume    = entry[10];

		System.out.println(number);
	*/

	@Override
	public void init(Site site)
	{
		this.site = site;
		try
		{
			csvReader = new CSVReader(new FileReader(PATH));
			
			dao = getDAO();
			
			titles = csvReader.readNext(); // skip titles
		}
		catch (FileNotFoundException e)
		{
			LOGGER.error(null, e);
			e.printStackTrace();
		}
		catch (IOException e)
		{
			LOGGER.error(null, e);
			e.printStackTrace();
		}
		
	}

	@Override
	public void init(String sitename)
	{
		dao = getDAO();
		
		site = dao.selectSiteByName(sitename);
		if (site == null)
		{
			LOGGER.warn(sitename + " was not found!");
			return;
		}
		
		init(site);
	}
	
	private ReadWriteDAO getDAO()
	{
		if (dao == null)
		{
			DAOFactory daoFactory = DAOFactory.getDAOFactory(DAOFactory.ORACLE);
			dao = daoFactory.getReadWriteDAO();
		}
		return dao;
	}
	
	@Override
	public boolean nextObject()
	{
		try
		{
			entry = csvReader.readNext();
		}
		catch (IOException e)
		{
			LOGGER.error(null, e);
			e.printStackTrace();
		}
		
		boolean hasNext = (entry != null);
		
		if (!hasNext)
		{
			try
			{
				csvReader.close();
			}
			catch (IOException e)
			{
				LOGGER.error(null, e);
				e.printStackTrace();
			}
		}
		
		return hasNext;
	}

	@Override
	public boolean isObjectExists()
	{
		Object object = dao.selectObjectBySiteAndName(site, entry[1]);
		
		return (object != null);
	}

	@Override
	public void createObject()
	{
		Object object = dao.createObject(site, entry[1]);
		object.save();
	}

	@Override
	public boolean checkAttributes()
	{
		Object object = dao.selectObjectBySiteAndName(site, entry[1]);
		if (object == null)
			return false;
		
		for (int i = 2; i <= 5; i++)
		{
			AttributeType attributeType = 
					dao.selectAttributeTypeByCode(titles[i]);
			if (attributeType == null)
				return false;
			
			Attribute attribute = 
					dao.selectAttributesByObjectAndType(object, attributeType);
			if (attribute == null)
				return false;
			if (!attribute.getValue().equals(entry[i]))
				return false;
		}
		
		return true;
	}

	@Override
	public void fillAttributes()
	{
		Object object = dao.selectObjectBySiteAndName(site, entry[1]);
		if (object == null)
			return;
		
		for (int i = 2; i <= 5; i++)
		{
			String code = titles[i];
			
			AttributeType attributeType = 
					dao.selectAttributeTypeByCode(code);
			if (attributeType == null)
			{
				attributeType = dao.createAttributeType(code, code);
				attributeType.save();
			}
			
			Attribute attribute = 
					dao.selectAttributesByObjectAndType(object, attributeType);
			if (attribute == null)
			{
				attribute = dao.createAttribute(object, attributeType);
				attribute.setValue(entry[i]);
				attribute.save();
				continue;
			}
			if (attribute.getValue() != entry[i])
			{
				attribute.setValue(entry[i]);
				attribute.save();
				continue;
			}
		}
	}

	@Override
	public void obtainStatistics()
	{
		Object object = dao.selectObjectBySiteAndName(site, entry[1]);
		if (object == null)
			return;
		
		for (int i = 6; i <= 10; i++)
		{
			String code = titles[i];
			
			StatsType statsType = dao.selectStatsTypeByCode(code);
			if (statsType == null)
			{
				statsType = dao.createStatsType(code, code);
				statsType.save();
			}
			
			Statistics statistics = dao.createStatistics(object, statsType);
			statistics.setValue(entry[i]);
			statistics.save();
		}
	}

}
